package org.example.service;

import java.nio.charset.StandardCharsets;
import java.util.Date;
import javax.crypto.spec.SecretKeySpec;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import jakarta.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class JwtTokenManager {
    @Value("${jwt.secret}")
    private String secretKey; // 签名密钥

    @Value("${jwt.expire-ms}")
    private long expireMs; // 过期时间（毫秒）

    private SecretKeySpec signingKey; // 加密密钥对象

    public long getExpireMs() {
        return this.expireMs;
    }

    public SecretKeySpec getSigningKey() {
        return this.signingKey;
    }

    // 初始化：将字符串密钥转换为SecretKey对象
    @PostConstruct
    public void init() {
        byte[] keyBytes = secretKey.getBytes(StandardCharsets.UTF_8);
        this.signingKey = new SecretKeySpec(
                keyBytes,
                SignatureAlgorithm.HS256.getJcaName());
    }
    // 生成唯一用户ID（简化实现）
    private String generateUserId() {
        return "GUEST_" + System.currentTimeMillis();
    }

    /**
     * 生成Token（基于device_id）
     *
     * @param deviceId 设备唯一标识
     * @return JWT Token字符串
     */
    public String generateToken(String deviceId) {
        return Jwts.builder()
                .setSubject(deviceId)
                .setId(generateUserId()) // 生成唯一用户ID
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + this.expireMs))
                .claim("deviceId", deviceId)
                .signWith(this.signingKey, SignatureAlgorithm.HS256)
                .compact();
    }

    /**
     * 验证Token并解析出device_id
     */
    public String validateTokenAndGetDeviceId(String authHeader) {
        String token = null;
        String bearer = "Bearer ";
        if (authHeader != null && authHeader.startsWith(bearer)) {
            token = authHeader.substring(bearer.length());
        }
        if (token == null) {
            throw new RuntimeException("未提供认证token");
        }
        // 解析Token
        Claims claims = Jwts.parserBuilder()
                .setSigningKey(this.signingKey) // 使用相同的Key对象
                .build()
                .parseClaimsJws(token)
                .getBody();

        // 验证Token是否过期（JWT已自动验证，这里可额外校验）
        if (claims.getExpiration().before(new Date())) {
            throw new ExpiredJwtException(null, null, "Token已过期");
        }

        // 提取device_id
        return (String) claims.get("deviceId");
    }
}
